/*
 * ToolButton.java  0.4.0 / Oct 27, 2010
 *
 * Copyright (c) 2010 - 2011, cute4j.com and contributors.
 *
 * This software is licensed under the LGPL version 2.1 license.
 * A copy of this license is included in the file LICENSE-LGPL.txt.
 */
package com.cute4j.swing;

import com.cute4j.swing.properties.ToolButtonProperties;

/**
 * Tool Button Component.
 *
 * @cute4j.native
 *    generate="header"
 *
 * @author Slobodan Vrkacevic
 * @version 0.4.0
 */
public class ToolButton extends AbstractButton implements ToolButtonProperties {

// Public Static Fields. -------------------------------------------------------

  /**
   * Icon only style (the value is {@value}).
   */
  public static final int STYLE_ICON_ONLY = 0;

  /**
   * Text only style (the value is {@value}).
   */
  public static final int STYLE_TEXT_ONLY = 1;

  /**
   * Text beside icon style (the value is {@value}).
   */
  public static final int STYLE_TEXT_BESIDE_ICON = 2;

  /**
   * Text under icon style (the value is {@value}).
   */
  public static final int STYLE_TEXT_UNDER_ICON = 3;

  /**
   * Delayed popup mode (the value is {@value}).
   */
  public static final int POPUP_MENU_DELAYED = 0;

  /**
   * Delayed popup mode (the value is {@value}).
   */
  public static final int POPUP_MENU_BUTTON = 1;

  /**
   * Delayed popup mode (the value is {@value}).
   */
  public static final int POPUP_MENU_INSTANT = 2;

// Private Fields. -------------------------------------------------------------

  private Menu menu;
  private int toolButtonStyle;
  private int menuPopupMode;
  private boolean menuPopupModeSet;

// Public Constructors. --------------------------------------------------------

  /**
   * Constructs new ToolButton object.
   */
  public ToolButton() {
    this(null, null);
  }

  /**
   * Constructs new ToolButton object.
   *
   * @param action the action
   */
  public ToolButton(Action action) {
    super(action);
  }

  /**
   * Constructs new ToolButton object.
   *
   * @param text the button text
   */
  public ToolButton(String text) {
    this(null, text);
  }

  /**
   * Constructs new ToolButton object.
   *
   * @param icon the button icon
   */
  public ToolButton(Icon icon) {
    this(icon, null);
  }

  /**
   * Constructs new ToolButton object.
   *
   * @param icon the button icon
   * @param text the button text
   */
  public ToolButton(Icon icon, String text) {
    super(text, icon);
    focusable = false;
    if ((icon != null) && (text != null)) {
      setToolButtonStyle(STYLE_TEXT_BESIDE_ICON); // NOPMD
    }
  }

// Public Methods. -------------------------------------------------------------

  /**
   * Returns tool button style.
   *
   * @return tool button style
   */
  public int getToolButtonStyle() {
    return toolButtonStyle;
  }

  /**
   * Sets tool button style.
   *
   * @param toolButtonStyle the tool button style
   */
  public void setToolButtonStyle(int toolButtonStyle) {
    if ((toolButtonStyle < STYLE_ICON_ONLY) ||
        (toolButtonStyle > STYLE_TEXT_UNDER_ICON)) {
      throw new IllegalArgumentException("Invalid tool button style");
    }
    final int oldToolButtonStyle = this.toolButtonStyle;
    if (oldToolButtonStyle != toolButtonStyle) {
      disposedCheck();
      _setToolButtonStyle(_delegate, toolButtonStyle);
      this.toolButtonStyle = toolButtonStyle;
      firePropertyChange(PROPERTY_TOOL_BUTTON_STYLE, oldToolButtonStyle,
                         toolButtonStyle);
    }
  }

  /**
   * Returns menu popup mode.
   *
   * @return menu popup mode
   */
  public int getMenuPopupMode() {
    return menuPopupMode;
  }

  /**
   * Sets menu popup mode.
   *
   * @param menuPopupMode the menu popup mode
   */
  public void setMenuPopupMode(int menuPopupMode) {
    if ((menuPopupMode < POPUP_MENU_DELAYED) ||
        (menuPopupMode > POPUP_MENU_INSTANT)) {
      throw new IllegalArgumentException("Invalid menu popup mode");
    }
    menuPopupModeSet = true;
    final int oldMenuPopupMode = this.menuPopupMode;
    if (oldMenuPopupMode != menuPopupMode) {
      disposedCheck();
      _setPopupMode(_delegate, menuPopupMode);
      this.menuPopupMode = menuPopupMode;
      firePropertyChange(PROPERTY_MENU_POPUP_MODE, oldMenuPopupMode,
                         menuPopupMode);
    }
  }

  /**
   * Returns button's menu.
   *
   * @return button's menu
   */
  public Menu getMenu() {
    return menu;
  }

  /**
   * Sets new menu and returns old.
   *
   * @param menu the menu
   *
   * @return old menu
   */
  public Menu setMenu(Menu menu) {
    Menu oldMenu = this.menu;
    if (oldMenu != menu) { // NOPMD
      disposedCheck();
      releaseComponent(oldMenu);
      if (menu == null) {
        _setMenu(_delegate, 0);
      } else {
        if (menu.isDisposed()) {
          throw new IllegalArgumentException("Menu disposed");
        }
        acquireFreeComponent(menu);
        _setMenu(_delegate, menu._delegate);
      }
      this.menu = menu;
      firePropertyChange(PROPERTY_MENU, oldMenu, menu);
      if (!menuPopupModeSet) {
        if (menu == null) {
          _setPopupMode(_delegate, POPUP_MENU_DELAYED);
        } else {
          _setPopupMode(_delegate, POPUP_MENU_BUTTON);
        }
      }
    }
    return oldMenu;
  }

// Overridden Methods. ---------------------------------------------------------

  /**
   * {@inheritDoc}
   */
  public void setComponentOrientation(ComponentOrientation orientation) {
    if (isOwnerOf(menu)) {
      menu.setComponentOrientation(orientation);
    }
    super.setComponentOrientation(orientation);
  }

  /**
   * {@inheritDoc}
   */
  public void updateLocalization() {
    if (isOwnerOf(menu)) {
      menu.updateLocalization();
    }
    super.updateLocalization();
  }

  /**
   * {@inheritDoc}
   */
  protected String paramString() {
    StringBuffer sb = new StringBuffer(super.paramString());
    if (isOwnerOf(menu)) {
      sb.append(",menu=");
      sb.append(menu);
    }
    return sb.toString();
  }

  void componentDestroyed() {
    super.componentDestroyed();
    if (isOwnerOf(menu)) {
      menu.dispose();
    }
  }

  /*!
   * @cute4j.native
   *    overridden="true"
   */
  void _styleSheetChanged(boolean removed) {
    if (isOwnerOf(menu)) {
      menu._styleSheetChanged(removed);
    }
    super._styleSheetChanged(removed);
  }

// Package-Private Native Methods. ---------------------------------------------

  native long _create();

  native void _setMenu(long delegate, long menuDelegate);

  native void _setPopupMode(long delegate, int popupMode);

  native void _setToolButtonStyle(long delegate, int toolButtonStyle);

}
